package cn.ulyer.core.modules.system.rest;

import cn.ulyer.common.annotation.Log;
import cn.ulyer.common.exception.BizException;
import cn.ulyer.common.jpa.entity.Permission;
import cn.ulyer.common.jpa.entity.QPermission;
import cn.ulyer.common.jpa.entity.Role;
import cn.ulyer.common.model.TreeVo;
import cn.ulyer.common.security.authority.AuthorityProvider;
import cn.ulyer.common.utils.Result;
import cn.ulyer.common.utils.SecurityUtil;
import cn.ulyer.common.utils.TreeUtil;
import cn.ulyer.core.modules.system.service.PermissionService;
import cn.ulyer.core.modules.system.service.RoleService;
import cn.ulyer.core.modules.system.vo.PermissionVo;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.ExecutionException;

@RestController
@RequestMapping("/permissionRest")
public class PermissionRestResource {


    private static final String MODULE = "permission";
    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AuthorityProvider authorityProvider;


    @GetMapping("/userMenus")
    public Result<List<TreeVo>> userPermission() {
        List<Role> roles = roleService.userRolesById(SecurityUtil.getUser().getId());
        return Result.ok().data(TreeUtil.listToTree(permissionService.PermissionVoByRoles(roles, Permission.PermissionType.MENU), 0));
    }

    @GetMapping("/list")
    public Result<List<TreeVo>> list(Permission permission) {
        Predicate predicate = null;
        if (permission != null) {
            QPermission qPermission = QPermission.permission;
            if (permission.getStatus() != null) {
                predicate = qPermission.status.eq(permission.getStatus());
            }
            if (permission.getPermissionType() != null) {
                ExpressionUtils.and(predicate, qPermission.permissionType.eq(permission.getPermissionType()));
            }
        }
        List<PermissionVo> menus = permissionService.allPermissionVo(predicate);
        return Result.ok().data(TreeUtil.listToTree(menus, 0));
    }


    @PostMapping("/create")
    @Log(module = MODULE, action = Log.ActionName.CREATE)
    public Result<String> create(@RequestBody @Valid Permission permission) throws ExecutionException, InterruptedException {
        if (permission.getParentId() == null) {
            permission.setParentId(0);
        }
        permission = permissionService.save(permission);
        authorityProvider.refresh();
        return Result.ok().data(permission.getId());
    }

    @PutMapping("/update")
    @Log(module = MODULE, action = Log.ActionName.UPDATE)
    public Result update(@RequestBody @Valid Permission permission) throws ExecutionException, InterruptedException {
        if (permission.getParentId() == null) {
            permission.setParentId(0);
        }
        permissionService.updateById(permission);
        authorityProvider.refresh();
        return Result.ok();
    }

    @DeleteMapping("/remove")
    @Log(module = MODULE, action = Log.ActionName.DELETE)
    public Result delete(@RequestParam Integer id) throws ExecutionException, InterruptedException {
        long result = permissionService.count(QPermission.permission.parentId.eq(id));
        if (result > 0) {
            throw new BizException("含有下级资源");
        }
        permissionService.deleteById(id);
        authorityProvider.refresh();
        return Result.ok();
    }


}
